//
//  AppManage.swift
//  SwiftZCC
//
//  Created by Mac mini on 2020/3/27.
//  Copyright © 2020 Mr.Hong. All rights reserved.
//

import UIKit
import Photos
import CoreLocation
import AVFoundation


// public：允许外部访问，不能被继承，重写
// open：权限最大，允许外部访问并可继承，重写

public struct CNMAppManage {
    public static let `default` = CNMAppManage()
    private init() {}
    
    /// 获取当前版本; plist中的 Version
    public func currentVersion() -> String {
        let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
        return version
    }

    /// 获取当前小版本; plist中的 Build
    public func currentBuild() -> String {
        let smVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
        return smVersion
    }
    
    /// 判断是否为新版本
    public func isNewVersion(_ currentVersion: String, with dbVersion: String) -> Bool {
        // 比较
        let result = compareVersion(currentVersion, with: dbVersion)
        
        // 如果存储的版本号为 nil 说明是第一次启动
        if result == 1 {
            return true
        }
        return false
    }
    
    /// 关于版本比较 (版本号相等, 返回0; cur小于db, 返回-1; cur大于db 返回1)
    public func compareVersion(_ currentVersion: String, with dbVersion: String) -> Int {
        // 版本(1.1.5) split返回 例子: ["1", "1", "5"]; compactMap(可去除nil元素) 返回 [1, 1, 5]
        var numbers1 = currentVersion.split(separator: ".").compactMap { Int($0) }
        var numbers2 = dbVersion.split(separator: ".").compactMap { Int($0) }
        
        let numberDiff = numbers1.count - numbers2.count
        if numberDiff < 0 {
            numbers1.append(contentsOf: Array(repeating: 0, count: abs(numberDiff)))
        } else if numberDiff > 0 {
            // 说明current版本的数字个数多于db版本的数字个数, db版本数字个数补0, 形成两者个数一致
            numbers2.append(contentsOf: Array(repeating: 0, count: numberDiff))
        }
        
        // 进行遍历, 对应位置元素相减, >/<0
        for i in 0..<numbers1.count {
            let diff = numbers1[i] - numbers2[i]
            
            if diff != 0 {
                return diff < 0 ? -1 : 1
            }
        }
        return 0
    }
}


// MARK: - 检查权限
/// 相机权限
public func cnm_checkCamera(_ resultHandle: @escaping (_ granted: Bool)->Void) {
    let status = AVCaptureDevice.authorizationStatus(for: .video)
    
    if status == .denied || status == .restricted {
        resultHandle(false)
    } else if (status == .notDetermined) {
        AVCaptureDevice.requestAccess(for: .video) { granted in
            DispatchQueue.main.async {
                if granted {
                    resultHandle(true)
                } else {
                    resultHandle(false)
                }
            }
        }
    } else {
        resultHandle(true)
    }
}

/// 相册权限
public func cnm_checkPhotoAlbumAuthority(_ resultHandle: @escaping (_ granted: Bool)->Void) {
    // .notDetermined: PHPhotoLibrary.requestAuthorization // 第一次操作代码
    let status = PHPhotoLibrary.authorizationStatus()

    if status == .restricted || status == .denied {
        resultHandle(false)
    } else {
        resultHandle(true)
    }
}

/// 麦克风权限
public func cnm_checkMICAuthority(_ handle: @escaping (_ granted: Bool)->Void) {
    let status = AVAudioSession.sharedInstance().recordPermission
    
    switch status {
    case .undetermined: // 第一次操作
        AVAudioSession.sharedInstance().requestRecordPermission { granted in
            if granted {
                handle(true)
            } else {
                handle(false)
            }
        }
    case .denied:
        handle(false)
    case .granted:
        handle(true)
    default:
        handle(false)
    }
}

/// 定位权限(Always + WhenInUse 根据plist描述设置)
public func cnm_checkLocationAuthority(_ handle: @escaping (_ granted: Bool)->Void) {
    let enabled = CLLocationManager.locationServicesEnabled()
    let status = CLLocationManager.authorizationStatus()
    
    if enabled && (status == .authorizedAlways ||
        status == .authorizedWhenInUse ||
        status == .notDetermined) {
        handle(true)
    } else {
        handle(false)
    }
}

/// 远程通知权限
public func cnm_checkRemoteNoticeficationAuthority(_ handle: @escaping (_ granted: Bool) -> Void) {
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            if settings.authorizationStatus == .denied ||
                settings.authorizationStatus == .notDetermined {
                // 没有权限
                DispatchQueue.main.async {
                    handle(false)
                }
            } else {
                DispatchQueue.main.async {
                    handle(true)
                }
            }
        }
    } else {
        if let isNotificationEnabled = UIApplication.shared.currentUserNotificationSettings?.types.contains(.alert) {
            if isNotificationEnabled == true {
                handle(true)
            } else {
                // 没有权限
                handle(false)
            }
        }
    }
}


/*
 知识点：将闭包包装成 async + await
 // 请求定位权限权限
 func checkLocationPermission() async -> Result<Bool, CNMError> {
     // 将闭包包装成 async + await
     await withCheckedContinuation { continuation in
         // 开启定位权限提示
         cnm_checkLocationAuthority { granted in
             var result: Result<Bool, CNMError>
             
             if granted {
                 result = .success(granted)
             } else {
                 result = .failure(.none)
             }
             continuation.resume(returning: result)
         }
     }
 }
 */
